package com.example.sxy.modbus4j;

import android.app.Activity;
import android.os.Bundle;
import android.renderscript.Element;
import android.view.Menu;
import android.view.MenuItem;
import android.widget.Toast;

import com.serotonin.modbus4j.BatchRead;
import com.serotonin.modbus4j.BatchResults;
import com.serotonin.modbus4j.ModbusFactory;
import com.serotonin.modbus4j.ModbusMaster;
import com.serotonin.modbus4j.code.DataType;
import com.serotonin.modbus4j.code.RegisterRange;
import com.serotonin.modbus4j.exception.ModbusInitException;
import com.serotonin.modbus4j.exception.ModbusTransportException;
import com.serotonin.modbus4j.ip.IpParameters;
import com.serotonin.modbus4j.locator.BaseLocator;
import com.serotonin.modbus4j.locator.NumericLocator;
import com.serotonin.modbus4j.msg.ReadHoldingRegistersRequest;
import com.serotonin.modbus4j.msg.ReadHoldingRegistersResponse;
import com.serotonin.modbus4j.msg.WriteRegisterRequest;
import com.serotonin.modbus4j.msg.WriteRegisterResponse;

import java.util.Arrays;


public class MainActivity extends Activity {
    private static final String IP = "192.168.0.25";
    private static final int SLAVEID = 1;
    private static final int PORT = 520;

    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_main);
        //1.创建IPParameters对象；(IP及端口号设置)
        IpParameters ipParameters = new IpParameters();
        ipParameters.setHost(IP);//设置IP地址
        ipParameters.setPort(PORT);//设置端口号
        ipParameters.setEncapsulated(false);
        Toast.makeText(MainActivity.this, "kaishi", Toast.LENGTH_LONG);
        //2.创建ModbusFactory对象；(用户创建ModbusMaster)
        ModbusFactory modbusFactory = new ModbusFactory();

        //3.根据上面两个对象创建ModbusMaster对象，并设置一些参数；
        ModbusMaster master = modbusFactory.createTcpMaster(ipParameters, false);
        master.setTimeout(8000);
        master.setRetries(0);
        try {
            master.init();
            //4.向寄存器中写数据
//            writeBatchTest(master);//批量写数据
            writeRegisterTest(master, SLAVEID, 2, 666);//单数据写入

        } catch (ModbusInitException e) {
            e.printStackTrace();
        }

        //5.采用下面三种方法中的一种获取数据；
//        singleReadTest(master);
//        readHoldingRegistersTest(master, 1, 1, 10);
//        readbatchTest(master);

        //6.销毁ModbusMaster对象。
        master.destroy();
    }

    /**
     * 批量写入数据。
     * @param master
     */
    public static void writeBatchTest(ModbusMaster master)
    {
        try{
            BaseLocator<Number> locator1 = BaseLocator.holdingRegister(SLAVEID, 1, DataType.TWO_BYTE_INT_UNSIGNED);
            BaseLocator<Number> locator2 = BaseLocator.holdingRegister(SLAVEID, 2, DataType.TWO_BYTE_INT_UNSIGNED);
            BaseLocator<Number> locator3 = BaseLocator.holdingRegister(SLAVEID, 3, DataType.TWO_BYTE_INT_UNSIGNED);
            BaseLocator<Number> locator4 = BaseLocator.holdingRegister(SLAVEID, 4, DataType.TWO_BYTE_INT_UNSIGNED);

            master.setValue(locator1, 1000);//设置数据
            master.setValue(locator2, 100);	//设置数据
            master.setValue(locator3, 10);	//设置数据
            master.setValue(locator4, 1);	//设置数据

            System.out.println(master.getValue(locator1));
            System.out.println(master.getValue(locator2));
            System.out.println(master.getValue(locator3));
            System.out.println(master.getValue(locator4));
        }catch(Exception e){
            e.printStackTrace();
        }
    }

    /**
     * 单数据书写，一次写一个数据。
     * @param master
     * @param slaveId
     * @param offset
     * @param value
     */
    public static void writeRegisterTest(final ModbusMaster master, final int slaveId, final int offset, final int value) {
        new Thread(){
            @Override
            public void run() {
                super.run();
                System.out.println("Thread is running.");
                try {
                    WriteRegisterRequest request = new WriteRegisterRequest(slaveId, offset, value);
                    WriteRegisterResponse response = (WriteRegisterResponse) master.send(request);

                    if (response.isException())
                        System.out.println("Exception response: message=" + response.getExceptionMessage());
                    else
                        System.out.println("Success");
                }
                catch (ModbusTransportException e) {
                    e.printStackTrace();
                }
            }
        }.start();
    }


    /**
     * 获取指定位置数据。
     */
    public static void singleReadTest(final ModbusMaster master) {
        new Thread(){
            public void run(){
                System.out.println("Thread is running.");
                NumericLocator el = new NumericLocator(1, RegisterRange.HOLDING_REGISTER, 1, DataType.TWO_BYTE_INT_UNSIGNED);
                NumericLocator fjk = new NumericLocator(1, RegisterRange.HOLDING_REGISTER, 3, DataType.TWO_BYTE_INT_UNSIGNED);

                for (int i = 0; i < 3; i++) {
                    try {
                        System.out.println("el: " + master.getValue(el));
                        System.out.println("fjk: " + master.getValue(fjk));
                    } catch (Exception e) {
                        e.printStackTrace();
                    }
                }
            }
        }.start();

    }

    /**
     * 读取连续数据。
     *
     * @param master
     * @param slaveId
     * @param start
     * @param len
     */
    public static void readHoldingRegistersTest(ModbusMaster master, int slaveId, int start, int len) {
        try {
            ReadHoldingRegistersRequest request = new ReadHoldingRegistersRequest(slaveId, start, len);
            ReadHoldingRegistersResponse response = (ReadHoldingRegistersResponse) master.send(request);

            if (response.isException())
                System.out.println("Exception response: message=" + response.getExceptionMessage());
            else
                System.out.println(Arrays.toString(response.getShortData()));
        } catch (ModbusTransportException e) {
            e.printStackTrace();
        }
    }

    /**
     * 读取批量不连续数据。
     */
    public static void readbatchTest(ModbusMaster master) {
        BatchRead<Integer> batch = new BatchRead<Integer>();
        batch.addLocator(0, BaseLocator.holdingRegister(1, 1, DataType.TWO_BYTE_INT_UNSIGNED));
        batch.addLocator(1, BaseLocator.holdingRegister(1, 3, DataType.TWO_BYTE_INT_UNSIGNED));

        try {
            master.init();
            batch.setContiguousRequests(false);
            BatchResults<Integer> results = master.send(batch);
            System.out.println(results.getValue(0));
            System.out.println(results.getValue(1));
        } catch (Exception e) {
            System.out.println(e.getMessage());
        } finally {
            master.destroy();
        }
    }


    @Override
    public boolean onCreateOptionsMenu(Menu menu) {
        // Inflate the menu; this adds items to the action bar if it is present.
        getMenuInflater().inflate(R.menu.menu_main, menu);
        return true;
    }

    @Override
    public boolean onOptionsItemSelected(MenuItem item) {
        // Handle action bar item clicks here. The action bar will
        // automatically handle clicks on the Home/Up button, so long
        // as you specify a parent activity in AndroidManifest.xml.
        int id = item.getItemId();

        //noinspection SimplifiableIfStatement
        if (id == R.id.action_settings) {
            return true;
        }

        return super.onOptionsItemSelected(item);
    }
}
